Next | Prev | Up | Top | Contents | Index

Conventional Synchronous I/O

Conventional I/O in UNIX is synchronous; that is, the process that requests the I/O is blocked until the I/O has completed. The effects are different for input and for output.


Synchronous Input

The normal sequence of operations for IRIX input is as follows:

  1. Normal code in a process invokes the system call read(), either directly or indirectly--for example, by accessing a new page of a memory-mapped file, or by calling a library function that calls read().

  2. The kernel, still operating under the identity of the calling process, enters the read entry point of the device driver.

  3. The device driver initiates the input operation and blocks the calling process, for example by waiting on a semaphore in the kernel address space.

  4. The kernel schedules another process to use the CPU.

  5. Later, the device completes the input operation and causes a hardware interrupt.

  6. The kernel interrupt handler enters the device driver interrupt entry point.

  7. The device driver, finding that the data has been received, unblocks the sleeping process, for example by posting a semaphore.

  8. The kernel recalculates the scheduling queues to account for the fact that a blocked process can now run.

  9. Then or perhaps later, depending on scheduling priorities, the kernel schedules the original process to run on some CPU.

  10. The unblocked process exits the device driver read function and returns to user code, the read being complete.
During steps 4-8, the process that requested input is blocked. The duration of the delay is unpredictable. For example, the delay can be negligible if the data is already in a buffer in memory. It can be as long as one rotation time of a disk, if the disk is positioned on the correct cylinder. It can be longer still, if the disk has to seek. The probability of seeking depends on the way the file is arranged on the disk surface and also on the I/O operations of other processes in the system.


Synchronous Output

For disk files, the process that calls write() is normally delayed only as long as it takes to copy the output data to a buffer in kernel address space. The device driver schedules the device write and returns. The actual disk output is asynchronous. As a result, most output requests are blocked for only a short time. However, since a number of disk writes could be pending, the true state of a file on disk is unknown until the file is closed.

In order to make sure that all data has been written to disk successfully, a process can call fsync() for a conventional file or msync() for a memory-mapped file (see the fsync(2) and msync(2) reference pages). The process that calls these functions is blocked until all buffered data has been written. (An alternative for disk output is to use direct output, discussed under "Synchronous Writing and Direct Writing".)

Devices other than disks may block the calling process until the output is complete. It is the device driver logic that determines whether a call to write() blocks the caller, and for how long. Device drivers for VME devices are often supplied by third parties.


Next | Prev | Up | Top | Contents | Index